#ifndef CPUSET_H
#define CPUSET_H
#include <unistd.h>
#include <limits.h>

/* from linux/sched.h */
#define PF_SIGNALED	0x00000400	/* killed by a signal */
#define PF_EXITING	0x00000004	/* getting shut down */
#define PF_THREAD_BOUND 0x04000000	/* process bound to a speciafic cpu */

//#define DEBUG
#define ENOCPU 65530
#define EBOUND 65529

//cpuset file system mount point
//static const char *cpusetmnt = "/cpuset";	
#define cpusetmnt 	"/cpuset/"
#define CHECKTASKS 	"/cpuset/tasks"
#define MEMSFILE	"cpuset.mems"
#define CPUSFILE	"cpuset.cpus"
#define TASKFILE	"tasks"
#define LOADBALANCE "cpuset.sched_load_balance"
#define HIDE		"..hide"
#define EXCLUDEFILE	"cpuset.cpu_exclusive"

#define EXECON      "/proc/self/execon"
//static const char *mask_size_file = "/proc/self/status";
//static const char *cpumask_prefix = "Cpus_allowed:\t";
//static const char *nodemask_prefix = "Mems_allowed:\t";
#define		mask_size_file  "/proc/self/status"
#define		cpumask_prefix  "Cpus_allowed:\t"
#define		cpumask_list_prefix  "Cpus_allowed_list:\t"
#define 	nodemask_prefix  "Mems_allowed:\t"
#define 	nodemask_list_prefix  "Mems_allowed_list:\t"
#define		migrate_file	"cpuset.migrate"
#define		lbarea_file		"cpuset.lbarea"

#define		online_cpu_file	"/sys/devices/system/cpu/online"

typedef enum {
	FLAG_NO,
	FLAG_OK,
	FLAG_NOPID,
}flag_t;

struct migrate {
		pid_t pid;
		int cpu;
		int force;
};

struct cpuset {
	char name[PATH_MAX];
	char cpulist[PATH_MAX];		//enough place
	char memlist[PATH_MAX];
	int lbarea;
	//TODO:expand
};
struct cpuset_pidlist {
	pid_t *pids;
	int npids;
};
#define LISTLEN	128
struct cpuset_namelist{
		char (*name)[PATH_MAX];
		char (*memlist)[LISTLEN];
		char (*cpulist)[LISTLEN];
		int num;
};

struct cpuset_fts_entry {
	struct cpuset_fts_entry *next;
	struct cpuset *cpuset;
	char *path;
	int info;
	int err;
};

struct cpuset_fts_tree {
	struct cpuset_fts_entry *head;
	struct cpuset_fts_entry *next;
};

extern int cpuset_dellbarea(const char *name);
extern void cpuset_dellbarea_all(void);
extern int cpuset_showlbarea();

extern int cpuset_getcpulist(pid_t pid, char *cpulist);
extern int cpuset_lbarea(const char *cpulist);
extern char *cpuset_lblist(void);

extern int cpuset_kill(const char *name, int force);

extern char *cpuset_getcpusetpath(pid_t pid, char *buf, size_t size);
extern int cpuset_getcpuset(const char *name, struct cpuset *cs);

extern int cpuset_create(struct cpuset *cs, void *nouse);

extern int cpuset_bind(pid_t pid, const char *relpath);
extern int cpuset_bind_cpuset_tasks(const char *fromrelpath, const char *torelpath);

extern int cpuset_rename(const char *oldname, const char *newname);


extern int cpuset_del_byname(const char *name, int force);
extern int cpuset_del_bypid(pid_t pid);

extern struct cpuset_pidlist *cpuset_getpid_begin(const char *name);
extern void cpuset_getpid_end(struct cpuset_pidlist *pl);

extern struct cpuset_namelist *cpuset_getname_begin();
extern void cpuset_getname_end(struct cpuset_namelist *nl);

extern int cpuset_migrate(pid_t pid, int cpu);

extern int cpuset_setcpulist(const char *path, const char *cpulist);

extern int cpuset_latestcpu(pid_t pid);
extern void ck_error(int status, int errnum, char *fmt, ...);
extern int cpuset_exec(char **name, int cpu);

#endif
